package cn.iocoder.yudao.module.pay.order.service;

import cn.iocoder.yudao.framework.common.pojo.PageResult;
import cn.iocoder.yudao.module.api.pay.order.dto.PayOrderCreateDTO;
import cn.iocoder.yudao.module.pay.order.dal.dataobject.PayOrderDO;
import cn.iocoder.yudao.module.pay.order.vo.*;
import jakarta.validation.Valid;

import java.time.LocalDateTime;
import java.util.Collection;
import java.util.List;
import java.util.Map;

/**
 * 付款单据 Service 实现类
 *
 * @author aquan
 */
public interface PayOrderService {

    /**
     * 获得付款单据
     *
     * @param id 支付比编号
     * @return 付款单据
     */
    PayOrderDO getOrder(Long id);

    /**
     * 获得付款单据
     *
     * @param no 支付单号
     * @return 付款单据
     */
    PayOrderDO getOrderByNo(String no);

    /**
     * 获得付款单据
     *
     * @param tradeNo 交易单号
     * @return 付款单据
     */
    PayOrderDO getOrderByTradeNo(String tradeNo);

    /**
     * 获得付款单据列表
     *
     * @param nos 支付单号数组
     * @return 付款单据列表
     */
    List<PayOrderDO> getOrderList(Collection<String> nos);

    /**
     * 获得付款单据分页
     *
     * @param pageReqVO 分页查询
     * @return 付款单据分页
     */
    PageResult<PayOrderDO> getOrderPage(PayOrderPageReqVO pageReqVO);

    /**
     * 获得付款单据列表, 用于 Excel 导出
     *
     * @param exportReqVO 查询条件
     * @return 付款单据列表
     */
    List<PayOrderDO> getOrderList(PayOrderExportReqVO exportReqVO);

    /**
     * 创建支付单
     *
     * @param dto 创建请求
     * @return 支付单信息
     */
    PayOrderDO createOrder(@Valid PayOrderCreateDTO dto);

    /**
     * 提交支付，此时，会发起支付渠道的调用
     *
     * @param reqVO  提交请求
     * @return 提交结果
     */
    PayOrderSubmitRespVO submitOrder(@Valid PayOrderSubmitReqVO reqVO);

    /**
     * 提交支付，此时，会发起支付渠道的调用
     *
     * @param userId  用户编号
     * @param reqVO  提交请求
     * @return 提交结果
     */
    PayOrderSubmitRespVO submitOrder(Long userId, @Valid AppPayOrderSubmitReqVO reqVO);

    /**
     * 更新付款单据的退款金额
     *
     * @param id             编号
     * @param incRefundPrice 增加的退款金额
     */
    void updateOrderRefundPrice(Long id, Integer incRefundPrice);

    /**
     * 商家/管理员修订单金额后，更新应付金额
     *
     * @param no       支付单号
     * @param payPrice 支付单价格
     */
    void updatePayOrderPrice(String no, Integer payPrice);

    /**
     * 同步第三方支付渠道的支付状态
     *
     * @param minCreateTime 最小创建时间
     * @return 同步到已支付的订单数量
     */
    int syncOrder(LocalDateTime minCreateTime);

    /**
     * 同步第三方支付渠道的支付状态
     *
     * @param order 支付单信息
     */
    boolean syncOrder(PayOrderDO order);

    /**
     * 同步第三方支付渠道的支付状态
     * <p>
     * 1. Quietly 表示，即使同步失败，也不会抛出异常
     * 2. 什么时候回出现异常？因为是主动同步，可能和支付渠道的异步回调存在并发冲突，导致抛出异常
     */
    PayOrderRespVO syncOrderQuietly(PayOrderDO order);

    /**
     * 同步订单的支付状态
     *
     * @return 同步到已支付的订单数量
     */
    int syncOrderByEmptyNotify();

    /**
     * 将已过期的订单，状态修改为已关闭
     *
     * @return 过期的订单数量
     */
    int expireOrder();

    /**
     * 支付回调
     *
     * @param channelCode 支付渠道
     * @param params 请求信息
     * @param body 请求信息
     * @param headers 请求信息
     * @return 回调结果
     */
    String notify(String channelCode, Map<String, String> params, String body, Map<String, String> headers);

    /**
     * 关闭支付单
     *
     * @param no 支付单号
     */
    void closeOrderByNo(String no);

    /**
     * 关闭支付单
     *
     * @param tradeNo 交易单号
     */
    void closeOrderByTradeNo(String tradeNo);

    /**
     * 获取所有微信支付成功的支付单号
     *
     * @param minDateTime 最小时间
     */
    List<String> getPayNoByWeChatPayed(LocalDateTime minDateTime);

}
